package com.zh.kotlin_mvvm.voice

import android.content.Context
import android.media.AudioAttributes
import android.media.MediaPlayer
import android.media.MediaRecorder
import android.text.format.DateFormat
import com.blankj.utilcode.util.LogUtils
import java.io.File
import java.io.IOException
import java.util.Calendar
import java.util.Locale


class AudioRecordPlayManager private constructor() {

    private var mMediaRecorder: MediaRecorder? = null
    private var mediaPlayer: MediaPlayer? = null

    companion object {

        @JvmStatic
        fun getInstance() = AudioRecordPlayManager()
    }

    fun startRecord(context: Context, callBack: (String) -> Unit) {
        // 开始录音
        /* ①Initial：实例化MediaRecorder对象 */
        if (mMediaRecorder == null) {
            mMediaRecorder = MediaRecorder()
        }
        try {
            /* ②setAudioSource/setVedioSource */
            mMediaRecorder?.setAudioSource(MediaRecorder.AudioSource.MIC)// 设置麦克风
            /*
             * ②设置输出文件的格式：THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式
             * ，H263视频/ARM音频编码)、MPEG-4、RAW_AMR(只支持音频且音频编码要求为AMR_NB)
             */
            mMediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT)
            mMediaRecorder?.setAudioSamplingRate(44100)
            /* ②设置音频文件的编码：AAC/AMR_NB/AMR_MB/Default 声音的（波形）的采样 */
            mMediaRecorder?.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT)
            mMediaRecorder?.setAudioEncodingBitRate(96000)
            val fileName =
                "${DateFormat.format("yyyyMMdd_HHmmss", Calendar.getInstance(Locale.CHINA))}.m4a"
            val audioSaveDir = File(context.externalCacheDir, "audioRecord")
            if (!audioSaveDir.exists()) {
                audioSaveDir.mkdirs()
            }
            val filePath = audioSaveDir.absolutePath + File.separator + fileName
            /* ③准备 */
            mMediaRecorder?.setOutputFile(filePath)
            mMediaRecorder?.prepare()
            /* ④开始 */
            mMediaRecorder?.start()
            callBack.invoke(filePath)
        } catch (e: IllegalStateException) {
            LogUtils.i("call startAmr (File mRecAudioFile) failed !&" + e.message)
        } catch (e: IOException) {
            LogUtils.i("call startAmr (File mRecAudioFile) failed !" + e.message)
        }
    }

    fun stopRecord() {
        mMediaRecorder?.stop()
        mMediaRecorder?.release()
        mMediaRecorder = null
    }

    fun playAudio(context: Context, path: String?) {
        if (path.isNullOrEmpty()) {
            return
        }
        stopPlayAudio()
        mediaPlayer = if (path.startsWith("http")) {
            MediaPlayer().apply {
                setAudioAttributes(AudioAttributes
                    .Builder()
                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                    .build())
                setDataSource(path)
                prepareAsync()
            }
        } else {
            MediaPlayer().apply {
                reset()
                setDataSource(path)
                prepareAsync()
            }
        }
        //音频播放完毕后调用
        mediaPlayer?.setOnCompletionListener {
            LogUtils.i("mediaPlayer: onCompletion---")
            stopPlayAudio()
        }
        //发生错误时调用
        mediaPlayer?.setOnErrorListener { mp, what, extra ->
            LogUtils.i("mediaPlayer: onError---")
            false
        }
        //音频源准备好后调用
        mediaPlayer?.setOnPreparedListener {
            LogUtils.i("mediaPlayer: onPrepared---")
            mediaPlayer?.start()
        }
        //网络流缓冲的状态变化时调用
        mediaPlayer?.setOnBufferingUpdateListener { mp, percent ->
            LogUtils.i("mediaPlayer: onBufferingUpdate---")
        }
        //Seek操作完成后调用
        mediaPlayer?.setOnSeekCompleteListener {
            LogUtils.i("mediaPlayer: onSeekComplete---")
            mediaPlayer?.start()
        }
    }

    fun seekTo(msec: Int) {
        mediaPlayer?.pause()
        mediaPlayer?.seekTo(msec)
    }

    fun pausePlayAudio() {
        mediaPlayer?.pause()
    }

    fun stopPlayAudio() {
        mediaPlayer?.stop()
        mediaPlayer?.release()
        mediaPlayer = null
    }
}